from HeaterDriver import HeaterDriver
from ThermistorDriver import ThermistorDriver
from DebugTrace import DebugTrace
from time import sleep

class HeaterController:
    def __init__(self,controller,pollinterval=1):
        self.thermistors= {"Bed":None, "Extruder0":None, "Extruder1":None}
        self.heaters={"Bed":None, "Extruder0":None, "Extruder1":None}
        self.running=True
        self.controller=controller
        self.pollInterval=pollinterval
        self.trace=DebugTrace("HeaterController",1)
        self.inputSR = None
        self.adc = None

    def addInputSR(self,inputSR):
        self.inputSR = inputSR
    
    def addADC(self, adc):
        self.adc = adc
        
    def getTemp(self, thermistor):
        self.adc.selectInput(thermistor)
        self.adc.convert() #read temp
        self.inputSR.readPins()
        self.inputSR.shiftAll()
        tempOutput = self.inputSR.getPinValues()[0:9] #first 10 values 
        multiplier = 1
        value = 0
        for a in tempOutput:
            value+= (multiplier * a)
            multiplier *= 2
        r1 = 0.0
        r2 = 4700.0
        r0 = 100000.0
        beta = 3974.0
        t0 = (25.0 + 273.15)
        vadc = 3.3
        vcc = 3.3
        rs = r2
        vs = vcc
        v = value * vadc / 1024.0          # convert the 10 bit ADC value to a voltage
        r = rs * v / (vs - v)     # resistance of thermistor
        k = r0 * math.exp(-1 * beta / t0)
        return (beta / math.log(r / k)) - 273.15        # temperature
 
        #v = adc * self.vadc / 1024          # convert the 10 bit ADC value to a voltage
        #r = self.rs * v / (self.vs - v)     # resistance of thermistor
        #return (self.beta / log(r / self.k)) - 273.15        # temperature
    
    def setHeater(self, thermistor, temp):
        self.thermistors[thermistor].setHoldingTemp(temp)
        self.trace.trace(2,thermistor+" Temperature set to "+str(temp))
        return "heater temperature set"

    def waitForHeater(self, thermistor):
        waitingTemp =  self.thermistors[thermistor].getHoldingTemp()
        while (self.thermistors[thermistor].getCurrentTemp() != waitingTemp):
            if(self.thermistors[thermistor].getCurrentTemp() < waitingTemp):
                self.thermistors[thermistor].HeaterDriver.enableHeater()
            elif(self.thermistors[thermistor].getCurrentTemp() > waitingTemp):
                self.thermistors[thermistor].HeaterDriver.disableHeater()
        return "heater ready"

    def heatControllerLoop(self):
        while self.running:
            sleep(self.pollInterval) #wait so that we aren't continuously getting the temp
            for therm in self.thermistors.iterkeys():
                if self.thermistors[therm]!=None:
                    self.trace.trace(3,"Polling thermistor "+therm)
                    waitingTemp =  self.thermistors[therm].getHoldingTemp()
                    self.thermistors[therm].setCurrentTemp(self.getTemp(self.thermistors[therm].HeaterDriver.getadcInput()))
                    curTemp=self.thermistors[therm].getCurrentTemp()
                    self.controller.cacheTemp(therm,curTemp)
                    if(curTemp < waitingTemp):
                        self.thermistors[therm].HeaterDriver.enableHeater()
                        self.trace.trace(3,"Thermistor "+therm+" below temp")

                    elif(curTemp > waitingTemp):
                        self.thermistors[therm].HeaterDriver.disableHeater()
                        self.trace.trace(3,"Thermistor "+therm+" above temp")